<template>
    <el-select
        :title="multiple? optionData.name : ''"
        ref="selectRef"
        v-model="currentValue"
        placeholder="请选择"
        clearable
        :disabled="props.disabled"
        :filterable="props.filterable"
        :filter-method="filterMethod"
        style="width: 215px;"
        @clear="clear"
        @visible-change="visibleChange"
    >
        <el-option ref="option" class="tree-select__option el-select-tree-out" :value="optionData.id" :label="optionData.name"
        >
            <el-tree
                ref="treeRef"
                class="tree-select__tree el-select-tree"
                :class="`tree-select__tree--${props.multiple ? 'checked' : 'radio'}`"
                :node-key="props.nodeKey"
                :data="props.data"
                :props="props.props"
                :default-expanded-keys="[currentValue || '']"
                :show-checkbox="props.multiple"
                :highlight-current="!props.multiple"
                :expand-on-click-node="props.multiple"
                :filter-node-method="filterNode"
                @node-click="handleNodeClick"
                @check-change="handleCheckChange"
            ></el-tree>
        </el-option>
    </el-select>
</template>

<script setup lang="ts" name="ElSelectTree">
import { computed, getCurrentInstance, nextTick, onBeforeMount, onMounted, reactive, ref, watch } from 'vue';
const props = defineProps({
    /* value: {
        type: String,
        default: ''
    }, */
    // v-model绑定
    modelValue: { // “modelValue"名字不能变
		default: ''
	},
    multiple: {
        type: Boolean,
        default: false
    },
    // 树形的数据
    data: {
        type: Array,
        default: function () {
            return []
        }
    },
    // 每个树节点用来作为唯一标识的属性
    nodeKey: {
        type: [String, Number],
        default: 'id'
    },
    filterable: {
        type: Boolean,
        default: false
    },
    disabled: {
        type: Boolean,
        default: false
    },
    // tree的props配置
    props: {
        type: Object,
        default: function () {
            return {
                label: 'label',
                children: 'children'
            }
        }
    }
});

let currentValue = ref(props.modelValue);
let optionData = reactive({
    id: '',
    name: ''
});
let filterFlag = ref(false);

// 定义emit事件
const emit = defineEmits(['update:modelValue', 'change']);
let selectRef = ref(null);
let treeRef = ref(null);
let proxy = getCurrentInstance() as any;
watch(()=>currentValue.value, (val)=>{
    if (!isEmpty(props.data)) {
        init(val)
    }
});
watch(()=>props.data,(val)=>{
    if (!isEmpty(val)) {
        init(currentValue.value)
    } 
});
// 是否为空
let isEmpty =(val)=> {
    for (let key in val) {
        return false
    }
    return true
};
let handleNodeClick=(data)=> {
    if (props.multiple) {
        return
    }
    currentValue.value = data[props.nodeKey];
    // props.modelValue = data[props.nodeKey];
    emit('update:modelValue', data[props.nodeKey])
    emit('change', data)
    selectRef.value.visible = false
};
let handleCheckChange=()=> {
    const nodes = treeRef.value.getCheckedNodes();
    const value = nodes.map((item) => item[props.nodeKey]).join(',')
    emit('update:modelValue', value)
};
let init=(val)=> {
    // 多选
    if (props.multiple) {
        const arr = val.toString().split(',')
        nextTick(() => {
            treeRef.value.setCheckedKeys(arr)
            const nodes = treeRef.value.getCheckedNodes()
            optionData.id = val
            optionData.name = nodes
                .map((item) => item[props.props.label])
                .join(',')
        })
    }
    // 单选
    else {
        val = val === '' ? null : val
        nextTick(() => {
            treeRef.value.setCurrentKey(val || '')
            if (val === null) {
                return
            }
            const node = treeRef.value.getNode(val)
            optionData.id = val            
            optionData.name = node && node.label;
        })
    }
};
let visibleChange=(e)=> {
    if (e) {
        filterFlag.value && treeRef.value.filter('')
        filterFlag.value = false
        let selectDom = null
        if(props.multiple) {
            selectDom = treeRef.value.$el.querySelector('.el-tree-node.is-checked')
        } else {
            selectDom = treeRef.value.$el.querySelector('.is-current')
        }
        nextTick(() => {
            selectRef.value.scrollToOption({ $el: selectDom })
        })
    }
};
let clear=()=> {
   emit('update:modelValue', '');
   emit('change', '');
};
let filterMethod=(val)=> {
    filterFlag.value = true
    treeRef.value.filter(val)
};
let filterNode=(value, data)=> {
    if (!value) return true
    const label = props.props.label || 'name'
    return data[label].indexOf(value) !== -1
}
</script>

<style lang="scss" scoped>
.tree-select__option {
    &.el-select-dropdown__item {
        height: auto;
        line-height: 1;
        padding: 0;
        background-color: #fff;
    }
}

.tree-select__tree {
    padding: 4px 8px;
    font-weight: 400;
    &.tree-select__tree--radio {
        .el-tree-node.is-current > .el-tree-node__content {
        //   color: $mainColor;
        font-weight: 700;
        }
    }
    :v-deep(.el-tree-node__content){
        height: 34px;
    }
}
</style>